home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 140_01.zip / YAMBOOT.C < prev    next >
Text File  |  1993-06-26  |  6KB  |  267 lines

  1. /* YAMBOOT.C by Steve Passe (Cnode SYSOP), 1981
  2.     
  3.    Modifications for Australian
  4.    conditions by Bill Bolton (Software Tools SYSOP), 1982
  5.  
  6. This program uses the "Christensen" MODEM7/YAM protocol for file
  7. transfers.  To receive a  type '<esc>', you will be prompted for
  8. the file name. (<esc> is the ASCII escape character: ^[).
  9.  
  10. Add whatever code necessary to the initialize_port() function (setup your
  11. port for 8 bits, 1 stop bit, baud rate of 300 if necessary, etc.).
  12. Using a serial modem you will have to make changes of port addresses and
  13. masks in the #ifdef modem area. There is a define CLKMHZ which should
  14. be set to the clock rate for your CPU.
  15.  
  16. This program uses large chunks of the YAM package for file transfers, 
  17. (thanks Chuck).
  18.  
  19. If you feel you need additional documentation try looking at the start
  20. of CMODEM.C which you may find relevant (or not). YAMBOOT should
  21. come straight up if you have BDSCIO.H set up correctly for your
  22. hardware, certainly if you have TELNET running. 
  23.  
  24. The strange stuff you see on the screen while it is running is normal,
  25. I didn't say it was pretty, only that it works!!!
  26.  
  27. */
  28.  
  29. #include "bdscio.h"        /* Must have modem defines setup */
  30.  
  31. #define SOH 0x01
  32. #define EOT 0x04
  33. #define ACK 0x06
  34. #define NAK 0x15
  35. #define CAN 0x18
  36. #define RETRYMAX 10
  37. #define TIMEOUT (-1)
  38. #define PATHLEN 20
  39. #define WCEOT (-2)
  40. #define CLKMHZ 4        /* CPU speed in Mhz */
  41.  
  42. #define CONSTAT 2
  43. #define CONIN 3
  44. #define DIR_IO 0x06        /* You have to have CP/M 2.2 */
  45. #define INPUT 0xff
  46. #define FLAG char
  47.  
  48. int Baud;
  49. FLAG Rfile;
  50. char Rname[PATHLEN];
  51. unsigned T1pause, Timeout;
  52. char File_buf[BUFSIZ];
  53. char Checksum, Lastrx;
  54. int Wcj, Firstch;
  55.  
  56. main()
  57. {
  58.     char received, to_send, in_modem(), getch(), escflag;
  59.     Rfile = FALSE;
  60.     T1pause = 311*CLKMHZ;
  61.     escflag = NULL;
  62.     Baud = 300;
  63.     initialize_port();
  64.     printf("\n\tYAMBOOT in the style of MBOOT.\n\n");
  65.     while (TRUE) {
  66.         if (received = in_modem()) putch(received);
  67.         else if (to_send = getch())
  68.             (to_send == ESC) ? download():out_modem(to_send);
  69.     }
  70. }
  71. char
  72. in_modem()
  73. {
  74.     if (inp(MSTAT) & MIMASK) return inp(MDATA);
  75.     else return FALSE;
  76. }
  77. out_modem(out_char)
  78. char out_char;
  79. {
  80.     while (!(inp(MSTAT) & MOMASK))    ;
  81.     outp(MDATA, out_char);
  82. }
  83. char
  84. getch()
  85. {
  86.     return bdos(DIR_IO, INPUT);
  87. }
  88.  
  89. /*
  90.  
  91.     Most of the following functions taken from YAM package by
  92. Chuck Forsberg, BDS C UG disk Utilities 3, some modifications made for
  93. compatibility with cnode code.
  94.  
  95. */
  96.  
  97. download(filename)
  98. char *filename;
  99. {
  100.     printf("\n\n\tReceive: ");
  101.     scanf("%s", Rname);
  102.     printf("ready to receive '%s'\n", Rname);
  103.     if(wcrx(Rname)==ERROR) {
  104.         abort();
  105.     }
  106.     return OK;
  107. }
  108.  
  109. /* Adapted from CMODEM13.C, by Jack M. Wierda and Roderick W. Hart */
  110. wcrx(name)
  111. char *name;
  112. {
  113.     int sectnum, sectcurr, sectcomp;
  114.     char *cp, rxbuf[128], sendchar;
  115.     if(openrx(name)==ERROR)
  116.         return ERROR;
  117.     sectnum=0;
  118.     sendchar=NAK;
  119.     for(;;) {
  120.         out_modem(sendchar);
  121.         sectcurr=wcgetsec(rxbuf, (sectnum & 0x7f) ? 50 : 130);
  122.         if(sectcurr==(sectnum+1 & 0xff)) {
  123.             sectnum++;
  124.             for(cp=rxbuf,Wcj=128; --Wcj>=0; )
  125.                 if(putc(*cp++, File_buf)==ERROR) {
  126.                     printf("\nDisk Full\n");
  127.                     return ERROR;
  128.                 }
  129.             sendchar=ACK;
  130.         }
  131.         else if(sectcurr==sectnum) {
  132.             printf("\nReceived dup Sector %d",sectcurr);
  133.             sendchar=ACK;
  134.         }
  135.         else if(sectcurr==WCEOT) {
  136.             out_modem(ACK);
  137.             closerx(FALSE);
  138.             return OK;
  139.         }
  140.         else {
  141.             printf(" Sync Error\n");
  142.             return ERROR;
  143.         }
  144.     }
  145. }
  146. wcgetsec(rxbuf, time)
  147. char *rxbuf;
  148. int time;
  149. {
  150.     int sectcurr,errors;
  151.     char *cp;
  152.  
  153.     for(Lastrx=errors=0; errors<RETRYMAX; errors++) {
  154.         do {
  155.             Firstch=readbyt(time);
  156.         }
  157.         while(Firstch != SOH && Firstch != TIMEOUT && Firstch != EOT
  158.               && Firstch != CAN);    /* wait for one of these */
  159.         if(Firstch==SOH) {
  160.             sectcurr=readbyt(1);
  161.             if((sectcurr+readbyt(1))==255) {
  162.                 Checksum=0;
  163.                 for(cp=rxbuf,Wcj=128; --Wcj>=0; ) {
  164.                     isprint(*cp = readbyt(1)) ? putchar(*cp) : putchar('.');
  165.                     Checksum += (*cp++);
  166.                 }
  167.                 if(((Checksum-readbyt(1))& 0xff)==0)
  168.                     return sectcurr;
  169.                 else
  170.                     printf("Checksum Error #%d", errors);
  171.             }
  172.             else
  173.                 printf("Sector number garbled #%d", errors);
  174.         }
  175.         else if(Firstch==EOT)
  176.             return WCEOT;
  177.         else if(Firstch==CAN) {
  178.             if(Lastrx==CAN) {
  179.                 printf("\nSender CANcelled");
  180.                 return ERROR;
  181.             } else {
  182.                 Lastrx=CAN;
  183.                 continue;
  184.             }
  185.         }
  186.         else if(Firstch==TIMEOUT)
  187.             printf("\nSOH Timeout #%d", errors);
  188.         Lastrx=0;
  189.         while(readbyt(1)!=TIMEOUT)
  190.             ;
  191.         out_modem(NAK);
  192.         time=40;
  193.     }
  194.     out_modem(CAN);out_modem(CAN);out_modem(CAN);
  195.     return ERROR;
  196. }
  197. openrx(name)
  198. char *name;
  199. {
  200.     printf("\nSaving it as '%s'", name);
  201.     if(fopen(name, File_buf) != ERROR) {
  202.         fclose(File_buf);
  203.         printf("\nI already have one, try another name");
  204.         return ERROR;
  205.     }
  206.     if(fcreat(name, File_buf)==ERROR){
  207.         printf("\nCan't create '%s'", name);
  208.         return ERROR;
  209.     }
  210.     Rfile= TRUE;
  211.     return OK;
  212. }
  213. readbyt(decisecs)
  214. int decisecs;
  215. {
  216.     if (inp(MSTAT) & MIMASK)
  217.         return inp(MDATA);
  218.     while (--decisecs >= 0) {
  219.         if (inp(MSTAT) & MIMASK)
  220.             return inp(MDATA);
  221.         if (bdos(DIR_IO, INPUT))
  222.             return TIMEOUT;
  223.         if (inp(MSTAT) & MIMASK)
  224.             return inp(MDATA);
  225.         for (Timeout = T1pause; --Timeout; )
  226.             if (inp(MSTAT) & MIMASK)
  227.                 return inp(MDATA);
  228.     }
  229.     return TIMEOUT;
  230. }
  231. abort()
  232. {
  233.     out_modem(CAN);out_modem(CAN);out_modem(CAN);
  234.     return ERROR;
  235. }
  236. closerx()
  237. {
  238.     if(Rfile) {
  239.         fflush(File_buf);
  240.         fclose(File_buf);
  241.         printf("\n\n%s closed", Rname);
  242.         Rfile=FALSE;
  243.     }
  244. }
  245. purgeline()
  246. {
  247.     while (inp(MSTAT) & MIMASK)
  248.         inp(MDATA);
  249. }
  250.  
  251. /* end of code from yam */
  252.  
  253. initialize_port()
  254. {
  255.     /* put your modem port intialisation code here, you may NOT need
  256.        it if you are CERTAIN that the port will be initialised
  257.        correctly before entering BOOTMODM */
  258. }
  259.  
  260. isprint(c)
  261. char c;
  262. {
  263.   return (c >= ' ' && c <= '~') || (c == 0x0d) || (c == 0x0a) || (c==0x09);
  264. }
  265.  
  266. /* END OF YAMBOOT */
  267.